        TITL DAI FIRMWARE 2EDF6-2EFFF  V1.0  Rev.1
        ORG   :EDF6
*
*
*
****************
* CURSOR RIGHT *
****************
*
* Moves cursor right one position.
*
* Exit: ABCDEHL preserved.
*       CY=0: Cursor not moved.
*       CY=1: Cursor moved.
*
ECRT    PUSH  D
        PUSH  H
        PUSH  PSW
        LDA   :00A8     Get offset of left side
 REM of window
        ADI   :3B       Calc end of window
        MOV   L,A       Result in L
        LDA   :00AB     Get X-offset of cursor
 REM in document
        CPI   :FF       Max nr char/line reached ?
        JZ    :ECDA     Then quit with CY=0
        CMP   L         End of window reached ?
        CZ    :ECF8     Then window right
        INR   A         Incr cursor pos on line
        STA   :00AB     Store X-offset of cursor
 REM in document
        XRA   A
        STA   :00AF     Clear cursor pos in buffer
        LHLD  :0072     Get cursor pos addr
        CALL  :E36B     Delete old cursor
        JMP   :ED6F     Put new cursor on screen;
 REM quit with CY=1
*
*****************************
* SKIP LINES IN EDIT BUFFER *
*****************************
*
* Entry: HL: Number of lines to be skipped.
* Exit:  HL: Points to 1st not skipped line.
*        CY=1: O.K.
*        CY=0: End of text reached before count
*              is zero.
*        ABCDE preserved.
*
L2E191  PUSH  D
        PUSH  PSW
        XCHG            Count in DE
        LHLD  :00A2     Get startaddr editbuf
L2E192  MOV   A,D       )
        ORA   E         ) Abort with CY=1 if ready
        JZ    :EE33     )
        CALL  :EE38     Next line
        NOP
        ORA   A
        JZ    :EE34     Abort with CY=0 if end of
 REM buffer reached before DE=0
        DCX   D         Count -1
        JMP   :EE22     Skip next line
L2E193  STC
L2E194  POP   D
        MOV   A,D
        POP   D
        RET
*
*************
* NEXT LINE *
*************
*
* Entry: HL: points to text, each line ended by
*            a car.ret, last line followed by 0.
* Exit:  HL: Points to next line.
*        A:  0 if end of text reached, else CR.
*        BCDE preserved.
*
L2E195  MOV   A,M       Get char from text
        ORA   A
        JZ    :EE43     Ready if end of text reached
        INX   H
        CPI   :0D       Car.ret ?
        JNZ   :EE38     Loop till end of line found
L2E196  RET
*
****************************************
* FIND CURRENT POSITION IN EDIT BUFFER *
****************************************
*
* Exit: CY=1: HL: (00AF/AE) = cursor position in
*                 buffer.
*       CY=0: HL: Points to cursor line in the
*                 edit buffer.
*       ABCDE preserved.
*
L2E197  LHLD  :00AE     Get pntr to cursor pos
 REM in buffer
        DCR   H
        INR   H
        STC
        RNZ             Quit (CY=1) if (AF) <> 0
        PUSH  D
        PUSH  B
        PUSH  PSW
        LHLD  :00AC     Get Y-offset of cursor
 REM in document (no lines to
 REM be skipped)
        MOV   D,H       ) in DE
        MOV   E,L       )
        CALL  :EE1C     Skip lines
        SHLD  :00B2     Store pntr to start cursor
 REM line in buffer
        PUSH  H         and preserve it
        LHLD  :00A9     Get offset of top of window
        CALL  :E6F2     Calc difference
        MVI   A,:86     Length one line
        CALL  :EB46     Calc total length
        XCHG            Result in DE
        LHLD  :008A     Get startaddr char area
        DAD   D         Add offset
        SHLD  :00B0     Preserve pntr to start
 REM cursor line on screen
        POP   H         Get pntr to start cursor
 REM line in buffer
        LDA   :00AB     Get X-offset of cursor
 REM in document
        MOV   B,A       in B
        CALL  :EE7B     Skip to Bth pos on line
 REM exit: HL pnts to cursor pos
        POP   B
        MOV   A,B
        POP   B
        POP   D
        CMC             Abort with CY=0
        RET
*
*************************************
* SKIP TO Bth POSITION ON TEXT LINE *
*************************************
*
* Looks through a textline until Bth position is
* found. On exit, character on this position is
* in A.
*
* Entry: HL: Start text line.
*        B:  Number of position in line.
* Exit:  CY=0: Position found:
*              A:  Character on that position.
*              HL: Points to Bth position.
*              BCDE preserved.
*        CY=1: Bth position is beyond car.ret,
*              tab or end of text.
*              HL: Points to CR, tab or 0.
*              A:  Space.
*
L2E198  PUSH  B
        PUSH  D
        MVI   C,:00     Init count
L2E199  JMP   :D1FD     Evaluate character
L2E200  JZ    :EEA3     Abort if Bth pos reached
        ORA   A         Set flags on char
        JZ    :EEA0     Jump if end of text reached
        CPI   :0D
        JZ    :EEA0     Jump if char is car.ret
        CPI   :09
        JZ    :EE98     Jump if char is tab
        INR   C         Incr count
L2E201  INX   H         Pnts to next pos on line
        JMP   :EE7F     Loop untill ready
 REM
* If character is tab:
 REM
L2E202  CALL  :EEA6     Tabulate
        MOV   A,B       Reqd pos in A
        CMP   C         Compare with tab stops
        JNC   :EE94     Continu if not past tab
 REM
* If end of line or end of text reached or if
* past tab:
 REM
L2E203  MVI   A,:20     Set char is space
        STC             Abort with CY=1
L2E204  POP   D
        POP   B
        RET
*
************
* TABULATE *
************
*
* Routine goes through tab-table for 1st
* tab-stop > C.
*
* Entry: 00B4/B5:  Pointer to tab-table.
*        C:        Line position.
* Exit:  If found: Tab in C.
*        Else:     C = C + 1.
*        AFBDEHL preserved.
*
L2E205  PUSH  PSW
        PUSH  B
        PUSH  H
        LHLD  :00B4     Get addr tab table
L2E206  MOV   B,C       Line pos in B
        INR   B         +1
        MOV   A,M       Get tab from table
        ORA   A
        JZ    :EEBA     If end tab table reached
        INX   H         Pnts to next tab
        MOV   B,A       Tab in B
        MOV   A,C       Line pos in A
        CMP   B
        JNC   :EEAC     Get next tab if line
 REM pos > tab stop
L2E207  MOV   C,B       Replace line pos by tab stop
 REM or by line pos +1 if no tab
 REM found
        POP   H
        POP   PSW
        MOV   B,A
        POP   PSW
        RET
*
********************************
* PRINT LINE OF TEXT IN WINDOW *
********************************
*
* Entry: HL:  Address of textline in buffer.
*        DE:  Line control byte of screen line
*             to print text on.
*        00A8: Number of non-printing positions.
*
* During execution loop:
*        B:   Nr of non-printing pos left +1.
*        C:   Nr of screen line pos left.
*        D:   Current text line position.
*        E:   Count of blanks inserted.
*        HL:  Points to text.
*        TOS: Points to screen.
*
L2E208  PUSH  B
        XCHG
        LXI   B,:FFF8
        DAD   B         1st printable pos on screen
        XCHG            in DE
        LDA   :00A8     Get offset of left side
 REM of window
        INR   A
        MOV   B,A       B is offset +1
        MVI   C,:3C     60 visible characters
        PUSH  D         Preserve start screen line
        MVI   D,:00     ) Init current text pos
        MOV   E,D       ) and blanks count
 REM
* Loop:
 REM
L2E209  MVI   A,:20     Space
        DCR   E
        INR   E
        JNZ   :EEEC     E<>0: Update screen pos pntr
        MOV   A,M       Else: Get char from buffer
        ORA   A         Set flags on char
        JMP   :D1D1     Test character
L2E210  CPI   :0D
        JZ    :EEEC     Skip tab-handling if CR
        MVI   E,:00     Reset blanks count
        INX   H         Pnts to next char in text
        CPI   :09       Tab ?
        JZ    :EF08     Then tab-handling
L2E211  INR   E
L2E212  DCR   E         Update blanks count
        INR   D         Update line position
        DCR   B         and nr of pos left in window
        JNZ   :EED2     No printing, cont with
 REM next char
        INR   B
        XTHL            Screen pos in HL
        MOV   M,A       Display char on screen
        DCX   H
        DCX   H         Next screen pos
        XTHL            Preserve it
        DCR   C         End of screen line reached ?
        JNZ   :EED2     Next char if not
        CALL  :EE38     Else: next line
        XTHL            HL is screen pos
        LXI   D,:FFFA
        DAD   D         HL is 1st useable pos
 REM on next line
        XCHG            into DE
        POP   H
        POP   B
        RET
 REM
* Tab-handling:
 REM
L2E213  PUSH  B
        MOV   C,D       C is pos on current line
        CALL  :EEA6     Tabulate
        MOV   A,C       Next tab stop in A
        SUB   D         ) Calc blanks to be inserted
        DCR   A         )
        MOV   E,A       Update blanks count
        POP   B
        MVI   A,:09     Restore tab char in A
        JMP   :EEEB
*
***************************
* PRINT A COMPLETE WINDOW *
***************************
*
* Text is printed in window from (DE) to bottom
* text screen if text ends. A ASCII 0 (vertical
* bar) is printed at the beginning of all
* following lines.
*
* Entry: HL: Points to text.
*        DE: Points to line control byte screen line
* Exit:  HL: Points to next line to print.
*        DE: Bottom text screen.
*        AF corrupted, BC preserved.
*
L2E214  PUSH  H
        LHLD  :008C     Get bottom text screen
        CALL  :E6FB     Compare HL-DE
        POP   H
        JZ    :EF28     Quit if window full
        CALL  :EEC0     Print a textline
        JMP   :EF17     Loop until ready
L2E215  RET
*
***************************************
* PRINT A TEXT LINE POINTED BY (00B2) *
* ON SCREEN POSITION (00B0) IN WINDOW *
***************************************
*
* Exit: All registers preserved.
*
L2E216  PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        LHLD  :00B0     Get pntr to start cursor
 REM line on screen
        XCHG            in DE
        LHLD  :00B2     Get pntr to start cursor
 REM line in buffer
        CALL  :EEC0     Print a text line
        JMP   :E138     Popall, ret
*
*********************
* PRINT FULL SCREEN *
*********************
*
* Prints from Nth line in full screen window.
* N is the offset of the top of the window from
* the start of the edit buffer.
*
* Exit: All registers preserved.
*
L2E217  PUSH  PSW
        PUSH  B
        PUSH  D
        PUSH  H
        LHLD  :008A     Get startaddr char area
        XCHG            in DE
        LHLD  :00A9     Get offset of top of window
        CALL  :EE1C     Skip lines
        JMP   :CE85     Print complete window
*
*
*
******************************
* INSERT CHARACTER IN BUFFER *
******************************
*
* Entry: Character in A.
* Exit:  ABCDEHL preserved.
*        CY=0: Buffer full, no action.
*        CY=1: Character inserted.
*
EINCH   PUSH  B
        PUSH  PSW
        PUSH  D
        PUSH  H
        MOV   B,A       Char in B
        LHLD  :00A6     Get end available space
        XCHG            in DE
        LHLD  :00A4     Get input pointer
        CALL  :E6FB     Compare HL-DE
        XCHG            Input pntr in E
        MOV   A,B       Char in A
        CC    :EE44     Space available: Find
 REM current pos in buffer
        JNC   :EF96     Buffer full: quit, char in A
        PUSH  H         Preserve end available space
        LHLD  :0072     Get cursor pos addr
        XTHL            Put it on stack
        PUSH  H
        CALL  :E36B     Delete cursor
        XCHG            Old input pntr in HL
        NOP
        INX   H         +1
        SHLD  :00A4     Update input pointer
        DCX   H
        MOV   B,H       ) Old input pntr in BC
        MOV   C,L       )
        DCX   H
        XCHG            Old input pntr -1 in DE
        POP   H         Get end available space
        DCX   H         -1
        CALL  :E6C2     Move screen area 1 pos
        INX   H
        MOV   M,A       Insert char in buffer
        INX   H
        SHLD  :00AE     Preserve pntr to cursor
 REM in buffer
        POP   H         Get end available space
        CPI   :0D
        JZ    :EF9C     Jump if char is car.ret
        CALL  :EF29     Reprint text line in window
        CALL  :E330     Put cursor on screen
        CPI   :09
        JZ    :EFB9     Jump if char is tab
        CALL  :EDF6     Move cursor right 1 pos
L2E218  STC
L2E219  POP   H
        POP   D
        POP   B
        MOV   A,B
        POP   B
        RET
 REM
* If car.ret:
 REM
L2E220  XRA   A
        STA   :00A8     )
        STA   :00AB     ) Reset pointers
        STA   :00AF     )
        CALL  :EF3A     Reprint full screen
        LHLD  :00B0     Get pntr to start cursor
 REM line on screen
        LXI   D,:FFF8
        DAD   D         New cursor addr
        CALL  :E330     Put cursor on screen
        CALL  :EDAB     Move cursor down
        JMP   :EF95     Quit with CY=1
 REM
* If tab:
 REM
L2E230  CALL  :EDF6     Move cursor right
        LDA   :00AB     Get X-offset of cursor
 REM in document
        MOV   B,A       in B
        LHLD  :00B2     Get pntr to start cursor
 REM line in buffer
        CALL  :EE7B     Skip to Bth pos on line
        JC    :EFB9     Again
        JMP   :EF95     Abort with CY=1
*
******************************
* DELETE CHARACTER IN BUFFER *
******************************
*
* Deletes character at cursor position and moves
* the text above this position. No action if past
* car.ret, tab or at or beyond end of text.
*
* Exit: ABCDEHL preserved.
*       CY=1: O.K.
*       CY=0: If past car.ret, tab or beyond 0.
*
EDLCH   PUSH  B
        PUSH  PSW
        PUSH  D
        PUSH  H
        CALL  :EE44     Find current pos in buffer
        JNC   :EF96     Quit if past CR, tab
 REM or 0 with CY=0
        MOV   A,M       Get char
        ORA   A
        JZ    :EF96     If at end of text:
 REM quit with CY=0
        NOP
        NOP
        NOP
        PUSH  H
        LHLD  :0072     Get cursor pos addr
        XTHL            preserve it on stack
        CALL  :E36B     Delete cursor
        XCHG            Original HL in DE
        LHLD  :00A4     Get input pointer
        DCX   H         Decrement it
        SHLD  :00A4     And store update input pntr
        MOV   B,H       ) Move updated pointer
        MOV   C,L       ) into BC
        DCX   B         Decrement it once again
        XCHG            restore original HL
        CALL  :E6C2     Move screen area above
 REM downwards
        CPI   :0D       Deleted car.ret ?
        CNZ   :EF29     If not: reprint text line
        CZ    :EF3A     Else: reprint full screen
        JMP   :CEF2     Put cursor on screen, abort
 REM with CY=1
*
*
*
        END
